package com.zcoj.controller.Admin.problem;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.lang.UUID;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zcoj.core.model.ApiResponse;
import com.zcoj.core.model.Constants;
import com.zcoj.core.model.PageWrap;
import com.zcoj.mapper.ProblemMapper;
import com.zcoj.pojo.Dto.Problem;
import com.zcoj.pojo.Dto.ProblemCase;
import com.zcoj.pojo.Dto.Source;
import com.zcoj.pojo.Dto.Tag;
import com.zcoj.pojo.Vo.ProblemCaseVO;
import com.zcoj.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.constraints.Size;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author chenbin
 * @version 1.0
 * @description: TODO
 * @date 2023/4/18 19:14
 */
@RequestMapping("/adminProblem")
@RestController
@PreAuthorize("hasAnyAuthority('super_admin','admin','problem_admin')")
public class adminProblemController {

    @Autowired
    private ProblemService problemService;

    @Autowired
    private ProblemMapper problemMapper;


    @Autowired
    private ProblemCaseService problemCaseService;



    @Autowired
    private SourceService problemSourceService;


    @Autowired
    private TagService problemTagService;


    @Autowired
    private XmlParserService xmlParserService;

    @PostMapping("/create")
    public ApiResponse create(@RequestBody Problem problem) {
        Integer integer = problemService.create(problem);
        if(integer!=0){
            return ApiResponse.success("添加成功",null);
        }else {
            return ApiResponse.failed("添加失败");
        }
    }

    /**
     * @method: [getProblemList]
     * @param: []
     * @returns: com.zcoj.core.model.ApiResponse
     * @description:  获取题目id  tilte
     * @author: chen.bin
     * @version: 1.0.0
     * @date 2023/4/21 20:56
     **/
    @GetMapping("/getProblemList")
    public ApiResponse getProblemList(){
        return ApiResponse.success(problemService.getProblemList());
    }







    /**
     * @method: [newProblemTestcaseFile]
     * @param: [fileName, pid]
     * @returns: com.zcoj.core.model.ApiResponse
     * @description:  题目建立测试目录
     * @author: chen.bin
     * @version: 1.0.0
     * @date 2023/4/20 15:39
     **/


    /**
     * @method: [newProblemTestcaseFile]
     * @param: [fileName, pid]
     * @returns: com.zcoj.core.model.ApiResponse
     * @description:    新建题目测试案例名称文件
     * @author: chen.bin
     * @version: 1.0.0
     * @date 2023/4/20 16:08
     **/
    @GetMapping("/createProblemTestcaseFile/{pid}/{fileName}")
    public ApiResponse newProblemTestcaseFile(@PathVariable String fileName,@PathVariable Integer pid){
        Integer integer = problemService.newProblemTestcaseFile(fileName, pid);
        if(integer==0){
            return ApiResponse.failed("数据库写入失败");
        }
        if(integer==-1){
            return ApiResponse.failed("创建文件失败");
        }
        return ApiResponse.success("创建成功",null);
    }
    /**
     * @method: [writeProblemCase]
     * @param: [problemCaseVO]
     * @returns: com.zcoj.core.model.ApiResponse
     * @description:  将内容写入测试案例
     * @author: chen.bin
     * @version: 1.0.0
     * @date 2023/4/20 23:00
     **/
    @PostMapping("/writeProblemCase")
    public ApiResponse writeProblemCase(@RequestBody ProblemCaseVO problemCaseVO) throws IOException {
        problemService.writeProblemCase(problemCaseVO);
        return ApiResponse.success("文件写入成功",null);
    }


    /**
     * @method: [readerProblemCase]
     * @param: [pid, filename]
     * @returns: com.zcoj.core.model.ApiResponse
     * @description:   读取单个文件传回前端
     * @author: chen.bin
     * @version: 1.0.0
     * @date 2023/4/20 22:30
     **/
    @GetMapping("/readerProblemCase/{pid}/{filename}")
    public ApiResponse readerProblemCase(@PathVariable Integer pid,@PathVariable String filename) throws FileNotFoundException {
        String fileName= Constants.File.TESTCASE_BASE_FOLDER.getPath()+"/problem_"+pid+"/"+filename;
        File file = new File(fileName);
        if(!FileUtil.exist(file)){
            throw new RuntimeException("文件不存在");
        }
        FileReader fileReader = new FileReader(fileName);
        String readString = fileReader.readString();
        return ApiResponse.success(readString);
    }



    /**
     * @method: [problemCaseFileList]
     * @param: [pid]
     * @returns: com.zcoj.core.model.ApiResponse
     * @description:  返回题目的测试数据列表
     * @author: chen.bin
     * @version: 1.0.0
     * @date 2023/4/20 22:57
     **/
    @GetMapping("/problemCaseFileList/{pid}")
    public ApiResponse problemCaseFileList(@PathVariable Integer pid){
        String fileName= Constants.File.TESTCASE_BASE_FOLDER.getPath()+"/problem_"+pid+"/";
        if(!FileUtil.exist(fileName)){
            throw new RuntimeException("路径不存在");
        }
        File[] ls = FileUtil.ls(fileName);
        List<String> list=new ArrayList<>();
        for (File f : ls) {
            list.add(FileNameUtil.getName(f));
        }
        return ApiResponse.success(list);
    }


    @GetMapping("/delProblemCaseFile/{pid}/{filename}")
    public ApiResponse delProblemCaseFile(@PathVariable Integer pid,@PathVariable String filename){
        String fileName=FileNameUtil.getPrefix(filename);
        String inFileName= Constants.File.TESTCASE_BASE_FOLDER.getPath()+"/problem_"+pid+"/"+fileName+".in";
        String outFileName= Constants.File.TESTCASE_BASE_FOLDER.getPath()+"/problem_"+pid+"/"+fileName+".out";

        ProblemCase problemCase = new ProblemCase();
        problemCase.setPid(pid);
        problemCase.setInput(fileName+".in");
        problemCase.setOutput(fileName+".out");
        ProblemCase one = problemCaseService.findOne(problemCase);
        if(Objects.nonNull(one)){
            problemCaseService.deleteById(one.getId());
            ProblemCase pc = new ProblemCase();
            pc.setPid(pid);
            List<ProblemCase> pclist = problemCaseService.findList(pc);
            if(pclist.size()!=0){
                Problem problemById = problemService.findById(pid);
                Integer score=problemById.getOiScore()/pclist.size();
                for(int i = 0; i < pclist.size()-1; i++) {
                    ProblemCase aCase = pclist.get(i);
                    aCase.setScore(score);
                    problemCaseService.updateById(aCase);
                }
                ProblemCase problemCase1 = pclist.get(pclist.size() - 1);
                if(score*pclist.size()==problemById.getOiScore()){
                    problemCase1.setScore(score);
                    problemCaseService.updateById(problemCase1);
                }else {
                    problemCase1.setScore(problemById.getOiScore()-score*(pclist.size()-1));
                    problemCaseService.updateById(problemCase1);
                }
            }

        }

        if(FileUtil.exist(new File(inFileName))&&FileUtil.exist(new File(outFileName))){
            FileUtil.del(new File(inFileName));
            FileUtil.del(new File(outFileName));
            QueryWrapper<Problem> problemQueryWrapper=new QueryWrapper<>();
            problemQueryWrapper.select("id","case_num");
            problemQueryWrapper.eq("id",pid);
            Problem problem = problemMapper.selectOne(problemQueryWrapper);
            if(Objects.nonNull(problem)){
                if(problem.getCaseNum()>0){
                    String uuidVersion= UUID.randomUUID().toString().substring(0,5);
                    problem.setCaseVersion(uuidVersion);
                    problem.setCaseNum(problem.getCaseNum()-1);
                    problemService.updateById(problem);
                }
            }

        }


        return ApiResponse.success("文件删除成功！！！",null);
    }

    @PostMapping("/problemList")
    public ApiResponse problemList(@RequestBody PageWrap<Problem> pageWrap){
        return ApiResponse.success(problemService.findPage(pageWrap));
    }


    @GetMapping("/delProblem/{id}")
    public ApiResponse delProblem(@PathVariable Integer id){
        Integer integer = problemService.deleteById(id);
        String problemPath= Constants.File.TESTCASE_BASE_FOLDER.getPath()+"/problem_"+id;
        FileUtil.del(new File(problemPath));
        if(integer!=0){
            return ApiResponse.success("删除成功",null);
        }else {
            return ApiResponse.failed("删除失败！！！");
        }
    }


    @PostMapping("/updateProblem")
    public ApiResponse updateProblem(@RequestBody Problem problem){
        Integer updateById = problemService.updateById(problem);
        if(updateById!=0){
            return ApiResponse.success("更新成功",null);
        }else {
            return ApiResponse.failed("更新失败！！！");
        }
    }

    @GetMapping("/getProblemById/{id}")
    public ApiResponse getProblemById(@PathVariable Integer id){
        return ApiResponse.success( problemService.findById(id));
    }



    /**
     * @method: [getProblemSourceTable]
     * @param: []
     * @returns: com.zcoj.core.model.ApiResponse
     * @description:   题目来源
     * @author: chen.bin
     * @version: 1.0.0
     * @date 2023/4/25 08:49
     **/


    @GetMapping("/getProblemSourceTable")
    public ApiResponse getProblemSourceTable(){
        return ApiResponse.success(problemSourceService.findAll());
    }


    @GetMapping("/deleteProblemSourceById/{id}")
    public ApiResponse deleteProblemSourceById(@PathVariable Integer id){
        Integer integer = problemSourceService.deleteById(id);
        if(integer!=0){
            return ApiResponse.success("删除成功");
        }else {
            return ApiResponse.failed("删除失败");
        }

    }


    @PostMapping("/createProblemSource")
    public ApiResponse createProblemSource(@RequestBody Source problemSource){
        if(Objects.nonNull(problemSource.getName())){
            problemSourceService.create(problemSource);
            if(Objects.nonNull(problemSource.getId())){
                return ApiResponse.success("创建成功");
            }else {
                return ApiResponse.failed("创建失败");
            }
        }else {
            return ApiResponse.failed("信息错误");
        }
    }


    @GetMapping("/findProblemSourceById/{id}")
    public ApiResponse findProblemSourceById(@PathVariable Integer id){
        Source byId = problemSourceService.findById(id);
        if(Objects.nonNull(byId)){
            return ApiResponse.success(byId);
        }else {
            return ApiResponse.failed("无此DiscussionCategoryId");
        }

    }

    @PostMapping("/updateProblemSource")
    public ApiResponse updateProblemSource(@RequestBody Source problemSource){
        Integer integer = problemSourceService.updateById(problemSource);
        if(integer!=0){
            return ApiResponse.success("更新成功");
        }else {
            return ApiResponse.failed("更新失败");
        }

    }






    /**
     * @method: [getProblemTagTable]
     * @param: []
     * @returns: com.zcoj.core.model.ApiResponse
     * @description:   题目标签
     * @author: chen.bin
     * @version: 1.0.0
     * @date 2023/4/25 08:48
     **/


    @GetMapping("/getProblemTagTable")
    public ApiResponse getProblemTagTable(){
        return ApiResponse.success(problemTagService.findList(new Tag()));
    }


    @GetMapping("/deleteProblemTagById/{id}")
    public ApiResponse deleteProblemTagById(@PathVariable Integer id){
        Integer integer = problemTagService.deleteById(id);
        if(integer!=0){
            return ApiResponse.success("删除成功");
        }else {
            return ApiResponse.failed("删除失败");
        }

    }


    @PostMapping("/createProblemTag")
    public ApiResponse createProblemTag(@RequestBody Tag problemTag){
        if(Objects.nonNull(problemTag.getName())){
            problemTagService.create(problemTag);
            if(Objects.nonNull(problemTag.getId())){
                return ApiResponse.success("创建成功");
            }else {
                return ApiResponse.failed("创建失败");
            }
        }else {
            return ApiResponse.failed("信息错误");
        }
    }


    @GetMapping("/findProblemTagById/{id}")
    public ApiResponse findProblemTagById(@PathVariable Integer id){
        Tag byId = problemTagService.findById(id);
        if(Objects.nonNull(byId)){
            return ApiResponse.success(byId);
        }else {
            return ApiResponse.failed("无此DiscussionCategoryId");
        }

    }

    @PostMapping("/updateProblemTag")
    public ApiResponse updateProblemTag(@RequestBody Tag problemTag){
        Integer integer = problemTagService.updateById(problemTag);
        if(integer!=0){
            return ApiResponse.success("更新成功");
        }else {
            return ApiResponse.failed("更新失败");
        }

    }

    @PostMapping("/uploadXmlProblemFile")
    public ApiResponse uploadXmlProblemFile(@RequestParam("file") @Size(max = 1024 * 1024, message = "文件大小不能超过1MB") MultipartFile file) throws Exception {
        System.out.println("uploadXmlProblemFile");

        if (file.isEmpty()) {
            return ApiResponse.failed("文件为空");
        }
        String content="";
        try {
            byte[] bytes = file.getBytes();
            content = new String(bytes, StandardCharsets.UTF_8);
        } catch (IOException e) {
            e.printStackTrace();
            return ApiResponse.failed("题目导入失败");
        }
        String status = xmlParserService.fpsXmlParseProblem(content);
        return ApiResponse.success(status,null);
    }
}
